package chapter02.item3Builder;

import java.util.EnumSet;
import java.util.Set;

/**
 * Builder pattern for class hierarchies
 */
public abstract class Pizza {

    /**
     * 火腿、蘑菇、洋葱、胡椒、香肠
     */
    public enum Topping {HAM, MUSHROOM, ONION, PEPPER, SAUSAGE}

    final Set<Topping> toppings;

    /**
     * Pizza.Builder 是一个带有递归类型参数（ recursive type parameter）的泛型类型
     * 这与抽象的 self 方法一起，允许方法链在子类中正常工作，而不需要强制转换。
     * <p>
     * Java 缺乏自我类型的这种变通解决方法被称为模拟自我类型
     *
     * @param <T>
     */
    abstract static class Builder<T extends Builder<T>> {
        /**
         * 创建一个空的Topping 枚举的空数据
         */
        EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);

        public T addTopping(Topping topping) {
            toppings.add(topping);

            return self();
        }

        abstract Pizza build();

        /**
         * 子类必须实现其功能并且返回自己
         * Subclasses must override this method to return "this"
         *
         * @return T
         */
        protected abstract T self();

    }

    Pizza(Builder<?> builder) {
        toppings = builder.toppings.clone();
    }
}
